/*
 * rentals.h
 *
 *  Created on: Apr 23, 2011
 *      Author: Yotam & Gilad
 */

#ifndef RENTALS_H_
#define RENTALS_H_

#include <stdio.h>

typedef struct Rentals_t *Rentals; /*this structure will hold all the info
 for the car rentals agency */

typedef enum {
	RENTALS_OUT_OF_MEMORY,	//	freeing all memory allocations and returns.
	RENTALS_CANNOT_OPEN_FILE,	//	defined for use in the calling function
	RENTALS_INVALID_COMMAND_LINE_PARAMETERS,	//	same as above
	RENTALS_CAR_ALREADY_EXISTS,
	RENTALS_CAR_IN_USE,
	RENTALS_CAR_DOES_NOT_EXISTS,
	RENTALS_CAR_ALREADY_ON_SALE,
	RENTALS_SALE_PRICE_TOO_BIG,
	RENTALS_CAR_NO_SALE,
	RENTALS_CUSTOMER_ALREADY_EXISTS,
	RENTALS_INVALID_CUSTOMER_ID,
	RENTALS_NO_CARS,
	RENTALS_NO_SALES,
	RENTALS_NO_OPEN_BILLS,
	RENTALS_INVALID_PRICE,
	RENTALS_INVALID_KM,
	RENTALS_INVALID_CAR,
	RENTALS_NULL_ARGUMENT,
	RENTALS_SUCCESS
} RentalsResult;

/**
 * rentalsCreateNew: initiates a new database to hold all the data.
 * return:
 * 	a pointer to the database
 * 	or NULL if memory allocation failed
 */
Rentals rentalsCreateNew();

/**
 * rentalsDestroy: recursively frees all the memory allocated for the rentals
 * 		program.
 *@param rental - the database to free all its memory
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 *	RENTALS_SUCCESS - otherwise
 */
RentalsResult rentalsDestroy(Rentals rentals);

/**
 * rentalsAddNewCar: adds a new car to the cars available for renting
 *@param rentals - the database to update
 *@param license - the license plate number of the new car
 *@param name - the name of the car
 *@param price - the price of the car for a km drive
 *@param km - the kilometerage of the newly added car
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 * 	RENTALS_INVALID_PRICE - if price is 0 or lower
 * 	RENTALS_INVALID_KM - if the kilometerage is lower then 0
 *  RENTALS_CAR_ALREADY_EXISTS - if the car already exists in the database
 *  RENTALS_OUT_OF_MEMORY - if memory allocation failed
 *  RENTALS_SUCCESS - otherwise.
 */
RentalsResult rentalsAddNewCar(Rentals rentals, int license, char* name,
		int price, int km);

/**
 * rentalsRemoveCar: removes a car from the database
 *@param license - the license plate number of the car to remove
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 *	RENTALS_CAR_DOES_NOT_EXISTS - if the car does not exist in the database
 *	RENTALS_CAR_IN_USE - if the car is in use at the moment and therefore
 *	can't be removed
 *	RENTALS_SUCCESS - otherwise.
 */
RentalsResult rentalsRemoveCar(Rentals rentals, int license);

/**
 * rentalsPutOnSale: places a car on sale
 *@param rentals - the database to update.
 *@param license - the license plate number of the car we'd like to update
 *@param minKm - the min kilometerage in which the sale starts to be effective
 *@param maxKm - the max kilometerage after which the sale stops being effective
 *@param salePrice - the price a customer will pay if driving withing the
 *		kilometerage limit.
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 *	RENTALS_INVALID_KM - if minKm is 0 or lower. or if maxKm < minKm
 *	RENTALS_INVALID_PRICE - if the sale price equals or lower than 0
 *	RENTALS_CAR_DOES_NOT_EXIST - if the car does not exist in the database
 *	RENTALS_CAR_IN_USE - if the car is in use at the moment
 *	RENTALS_ALREADY_ON_SALE	- if the car is already on sale
 *	RENTALS_SALE_PRICE_TOO_BIG - if price of the car while on sale might be
 *		higher or equal to the price when not on sale.
 *	RENTALS_SUCCESS - otherwise.
 */
RentalsResult rentalsPutOnSale(Rentals rentals, int license, int minKm,
		int maxKm, int salePrice);

/**
 * rentalsEndSale: end a sale for a car
 *@param rentals - the database to update
 *@param license - the license plate number of the car to end it's sale
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 *	RENTALS_CAR_DOES_NOT_EXIST - if the car does not exist in the database
 *	RENTALS_CAR_IN_USE - if the car is currently rented to a customer
 *	RENTALS_CAR_NO_SALE - if the car is not currently on sale
 *	RENTALS_SUCCESS - otherwise
 */
RentalsResult rentalsEndSale(Rentals rentals, int license);

/**
 * rentalsAddNewCustomer: adds a new customer to the database
 *@param rentals - the database to update
 *@param id - the new customer's id
 *@param name - the new customer's name
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 *	RENTALS_CUSTOMER_ALREADY_EXIST - if a customer with the same id
 *		is already in the database
 *	RENTALS_OUT_OF_MEMORY - if memory allocation failed and a new customer
 *		and the new customer couldn't be added
 *	RENTALS_SUCCESS - otherwise
 */
RentalsResult rentalsAddNewCustomer(Rentals rentals, int id, char* name);

/**
 * rentalsCustomerRentCar: updates the database to indicate a car is rented
 * 		to a customer.
 *@param rentals - the database to update
 *@param id - the customer's id
 *@param license - the license plate number of the car
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 *	RENTALS_CAR_DOES_NOT_EXIST - if the car does not exist in the database
 *	RENTALS_CAR_IN_USE - if the car is already in use
 *	RENTALS_INVALID_CUSTOMER_ID - if the ID given is not in the database
 *	RENTALS_OUT_OF_MEMORY - if memory allocation failed
 *	RENTALS_SUCCESS - otherwise
 */
RentalsResult rentalsCustomerRentCar(Rentals rentals, int id, int license);

/**
 * rentalsCustomerReturnCar: updates the database to indicate a customer
 * 		returned a car after a certain driving distance.
 *@param rentals - the database to update
 *@param id - the customer's id
 *@param license - the car's license plate number
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 *	RENTALS_INVALID_CUSTOMER_ID - the id doesn't exist in the database
 *	RENTALS_INVALID_KM - the distance given is less or equals 0
 *	RENTALS_INVALID_CAR - the car is not rented by that customer
 *	RENTALS_OUT_OF_MEMORY - if memory allocation failed.
 *	RENTALS_SUCCESS - otherwise.
 */
RentalsResult rentalsCustomerReturnCar(Rentals rentals, int id, int license,
		int km);

/**
 * rentalsCustomerPayBill: updates the database to indicate a customer payed its
 * 		bill.
 *@param rentals - the database to update
 *@param id - the customer's id
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 *	RENTALS_INVALID_CUSTOMER_ID - if there is no customer with that id in the
 *	database, or if the customer doesn't have an open bill
 *	RENTALS_SUCCESS - otherwise.
 */
RentalsResult rentalsCustomerPayBill(Rentals rentals, int id);

/**
 * rentalsGetCarsAvailable: prints a list of available cars sorted first by
 * 		their name and then by kilometerage.
 *@param rentals - the rentals database
 *@param output - the output destination to be sent to the mtm printing function
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 *	RENTALS_OUT_OF_MEMORY - if memory allocation failed
 *	RENTALS_NO_CARS - if no cars are available.
 *	RENTALS_SUCCESS - otherwise.
 */
RentalsResult rentalsPrintAvailableCars(Rentals rentals, FILE* output);

/**
 * rentalsPrintOpenBills: prints a list of open	customer bills sorted first by
 * 		the bill sum and then by the customer ID
 *@param rentals - the rentals database
 *@param output - the output destination to be sent to the mtm printing function
 *return:
 *	RENTALS_NULL_ARGUMENT - if rentals is NULL
 *	RENTALS_OUT_OF_MEMORY - if memory allocation failed
 *	RENTALS_NO_OPEN_BILLS - if there are no open bills
 *	RENTALS_SUCCESS - otherwise.
 */
RentalsResult rentalsPrintOpenBills(Rentals rentals, FILE* output);

/**
 * rentalsPrintCusotmerBill: prints the bill of a customer.
 *@param rentals - the rentals database.
 *@param id - the customer's id.
 *@param output - the output destination to be sent to the mtm printing function
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 *	RENTALS_INVALID_CUSTOMER_ID - if the id doesn't exist in the database.
 *	RENTALS_OUT_OF_MEMORY - if memory allocation failed
 *	RENTALS_SUCCESS - otherwise.
 */
RentalsResult rentalsPrintCustomerBill(Rentals rentals, int id, FILE* output);

/**
 * rentalsPrintIncomeSummary: prints a summary including the number of cars
 * 		returned and payed for, the income since last time checked, and the
 * 		average bill sum.
 *@param rentals - the database to summarize from.
 *@param output - the output destination to be sent to the mtm printing function
 *return:
 *	RENTALS_NULL_ ARGUMENT - if rentals is NULL
 *	RENTALS_NO_SALES - if no payments have been made since last check.
 *	RENTALS_SUCCESS - otherwise.
 */
RentalsResult rentalsPrintIncomeSummary(Rentals rentals, FILE* output);

#endif /* RENTALS_H_ */
